/***********************************************************************************************************************
/*
/*  CamTool
/*
/*  begun February 4, 2010
/*
/*  main.cpp
/*
/**********************************************************************************************************************/

#include "stdafx.h"


//======================================================================================================================
//  PROTOTYPES
//======================================================================================================================

INT_PTR CALLBACK dialog_proc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
void init_common_controls ();
void set_state ();


//======================================================================================================================
//  DATA
//======================================================================================================================

cVersion g_Version ( 0, 0, 0, 7 );
cSettings g_Settings;
HWND g_hwnd;
HWND g_hwndMini;
wchar_t g_awAppTitle [] = L"CamTool";


//======================================================================================================================
//  CODE
//======================================================================================================================


//----------------------------------------------------------------------------------------------------------------------
// MAIN
//----------------------------------------------------------------------------------------------------------------------
int WINAPI wWinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR pCmdLine, int iCmdShow )
{
	UNREFERENCED_PARAMETER ( pCmdLine );
	UNREFERENCED_PARAMETER ( iCmdShow );
	UNREFERENCED_PARAMETER ( hPrevInstance );

	if ( previous_instance_is_running () )
		return 0;

	init_common_controls();

	start_low_priority_thread ();

	//----------------------------------------------
	// LOAD OUR SETTINGS
	//----------------------------------------------
	{
		cStrW sPath;
		get_our_local_app_data_directory ( &sPath, g_awAppTitle );
		sPath += g_awAppTitle;
		sPath += L".settings.txt";
		g_Settings.set_pathname ( sPath.cstr() );
		g_Settings.load_from_file ();
	}

	g_hwnd     = CreateDialogParam ( hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, dialog_proc, 0 );
	set_dialog_icon ( g_hwnd, IDI_ICON );
	g_hwndMini = CreateDialogParam ( hInstance, MAKEINTRESOURCE(IDD_MINI), NULL, dialog_proc, 0 );
	set_dialog_icon ( g_hwndMini, IDI_ICON );

	set_state();

    if  ( ! g_hwnd )
		exit(0);

	if ( -1 != g_Settings.ptMainWindowPosition.x && -1 != g_Settings.ptMainWindowPosition.y )
	{
		SetWindowPos ( g_hwnd,     NULL, g_Settings.ptMainWindowPosition.x, g_Settings.ptMainWindowPosition.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
		SetWindowPos ( g_hwndMini, NULL, g_Settings.ptMainWindowPosition.x, g_Settings.ptMainWindowPosition.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
	}

	add_tray_icon ( LoadIcon ( hInstance, MAKEINTRESOURCE ( IDI_ICON ) ) );

    MSG uMsg;
    int iResult;

    while ( 0 != ( iResult = GetMessage ( & uMsg, 0, 0, 0 ) ) )
    {
        if ( -1 == iResult )
            return -1;

        if ( ! IsDialogMessage ( g_hwnd, & uMsg ))
        {
            TranslateMessage ( & uMsg );
            DispatchMessage ( & uMsg );
        }
    }

    return uMsg.wParam;
}

//----------------------------------------------------------------------------------------------------------------------
// CLEAN UP FOR EXIT
//----------------------------------------------------------------------------------------------------------------------
void clean_up_for_exit ()
{
	g_Settings.save_to_file();
	set_default_gamma ();
	remove_tray_icon();
}

//----------------------------------------------------------------------------------------------------------------------
// INIT COMMON CONTROLS
//----------------------------------------------------------------------------------------------------------------------
void init_common_controls ()
{
	INITCOMMONCONTROLSEX sex;

	ZeroMemory ( &sex, sizeof(sex) );
	sex.dwSize = sizeof(sex);
	sex.dwICC = ICC_LISTVIEW_CLASSES | ICC_BAR_CLASSES | ICC_STANDARD_CLASSES;
	InitCommonControlsEx ( &sex );
}

//----------------------------------------------------------------------------------------------------------------------
// SET STATE
//----------------------------------------------------------------------------------------------------------------------
void set_state ()
{
	BOOLEAN f = g_Settings.bOn ? TRUE : FALSE;

	if ( g_Settings.bOn )
	{
		Button_SetCheck ( GetDlgItem ( g_hwnd, ID_ON ), TRUE );
		Button_SetCheck ( GetDlgItem ( g_hwndMini, ID_ON ), TRUE );
		Button_SetCheck ( GetDlgItem ( g_hwnd, ID_OFF ), FALSE );
		Button_SetCheck ( GetDlgItem ( g_hwndMini, ID_OFF ), FALSE );

	}

	else
	{
		Button_SetCheck ( GetDlgItem ( g_hwnd, ID_ON ), FALSE );
		Button_SetCheck ( GetDlgItem ( g_hwndMini, ID_ON ), FALSE );
		Button_SetCheck ( GetDlgItem ( g_hwnd, ID_OFF ), TRUE );
		Button_SetCheck ( GetDlgItem ( g_hwndMini, ID_OFF ), TRUE );
	}

	EnableWindow ( GetDlgItem ( g_hwnd, ID_BRIGHTNESS ), f );
	EnableWindow ( GetDlgItem ( g_hwnd, ID_CONTRAST ), f );
	EnableWindow ( GetDlgItem ( g_hwnd, ID_GAMMA ), f );
	EnableWindow ( GetDlgItem ( g_hwnd, ID_DEFAULTS ), f );

	EnableWindow ( GetDlgItem ( g_hwnd, ID_BRIGHTNESS_CAPTION ), f );
	EnableWindow ( GetDlgItem ( g_hwnd, ID_CONTRAST_CAPTION ), f );
	EnableWindow ( GetDlgItem ( g_hwnd, ID_GAMMA_CAPTION ), f );

	if ( g_Settings.bExpanded )
	{
		ShowWindow ( g_hwnd, SW_SHOW );
		ShowWindow ( g_hwndMini, SW_HIDE );
	}

	else
	{
		ShowWindow ( g_hwnd, SW_HIDE );
		ShowWindow ( g_hwndMini, SW_SHOW );
	}
}

//----------------------------------------------------------------------------------------------------------------------
//  ON MINIMIZE
//----------------------------------------------------------------------------------------------------------------------
void on_minimize ()
{

#if 1
	HWND hwnd = g_Settings.bExpanded ? g_hwnd : g_hwndMini;
	ShowWindow ( hwnd, SW_MINIMIZE );
	// Sleep(200);
	// ShowWindow ( hwnd, SW_HIDE );

#else

	APPBARDATA abd;
	memset ( &abd, 0, sizeof(abd) );
	abd.cbSize = sizeof(abd);
	BOOL fResult = (BOOL) SHAppBarMessage ( ABM_GETTASKBARPOS, &abd); 
	fResult;

	RECT rT = abd.rc;
	HWND hwnd = g_Settings.bExpanded ? g_hwnd : g_hwndMini;
	TITLEBARINFO tbi = { 0 };
	tbi.cbSize = sizeof(tbi);

	GetTitleBarInfo ( hwnd, &tbi);

	RECT rW;
	GetWindowRect ( hwnd, & rW );

	if ( ! DrawAnimatedRects ( hwnd, IDANI_CAPTION, &rW, &rT ) )
	{
		DWORD dwError = GetLastError();
		dwError;
		int x =3 ;
		x++;
	}

	ShowWindow ( hwnd, SW_HIDE);

#endif
}

//----------------------------------------------------------------------------------------------------------------------
// DIALOG PROC
//----------------------------------------------------------------------------------------------------------------------
INT_PTR CALLBACK dialog_proc ( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	UNREFERENCED_PARAMETER(lParam);

	if ( uWM_ARE_YOU_ME == uMsg )
	{
		SetWindowLongPtr ( hwnd, DWLP_MSGRESULT, uWM_ARE_YOU_ME );
		return true;
	}

	switch ( uMsg )
	{
	case uWM_TRAY_ICON:
		wm_tray_icon ( wParam, lParam );
		break;

	case WM_MOVE:
		{
			RECT r;
			GetWindowRect ( hwnd, &r );
			g_Settings.ptMainWindowPosition.x = r.left;
			g_Settings.ptMainWindowPosition.y = r.top;
		}
		break;

	case WM_SYSCOMMAND:
		switch ( wParam )
		{
		case SC_MINIMIZE:
			{
				on_minimize();
				return TRUE;
			}
			break;
		}
		break;


	case WM_ACTIVATE:
		// update_gamma ();
		break;

	case WM_INITDIALOG:
		{
			SendMessage ( GetDlgItem ( hwnd, ID_GAMMA ), TBM_SETRANGE, TRUE, MAKELONG(25,400) );  // returns LRESULT in lResult
			SendMessage ( GetDlgItem ( hwnd, ID_GAMMA ), TBM_SETPOS, TRUE, LPARAM ( g_Settings.uGamma ) );
			SendMessage ( GetDlgItem ( hwnd, ID_GAMMA ), TBM_SETTIC, 0, (LPARAM) 100 );

			SendMessage ( GetDlgItem ( hwnd, ID_BRIGHTNESS ), TBM_SETRANGE, TRUE, MAKELONG(0,100) );  // returns LRESULT in lResult
			SendMessage ( GetDlgItem ( hwnd, ID_BRIGHTNESS ), TBM_SETPOS, TRUE, LPARAM ( g_Settings.uBrightness ) );
			SendMessage ( GetDlgItem ( hwnd, ID_BRIGHTNESS ), TBM_SETTIC, 0, (LPARAM) 50 );

			SendMessage ( GetDlgItem ( hwnd, ID_CONTRAST ), TBM_SETRANGE, TRUE, MAKELONG(0,100) );  // returns LRESULT in lResult
			SendMessage ( GetDlgItem ( hwnd, ID_CONTRAST ), TBM_SETPOS, TRUE, LPARAM ( g_Settings.uContrast) );
			SendMessage ( GetDlgItem ( hwnd, ID_CONTRAST ), TBM_SETTIC, 0, (LPARAM) 50 );

			if ( g_Settings.bOn )
			{
				// Button_SetCheck ( GetDlgItem ( hwnd, ID_ON ), TRUE );
				// Button_SetCheck ( GetDlgItem ( hwnd, ID_OFF), FALSE);
				set_gamma_ramp ( ((double)g_Settings.uGamma)/100, g_Settings.uBrightness, g_Settings.uContrast );
			}

			else
			{
				// Button_SetCheck ( GetDlgItem ( hwnd, ID_ON ), FALSE );
				// Button_SetCheck ( GetDlgItem ( hwnd, ID_OFF), TRUE);
				set_default_gamma ();
			}

			set_state ();

			wchar_t awCaption[200];
			wsprintf ( awCaption, L"%s build %d", g_awAppTitle, g_Version.uBld );
			SetWindowText ( hwnd, awCaption );

		}
		return (INT_PTR)TRUE;

	case WM_HSCROLL:

			if ( (HWND) lParam == GetDlgItem ( hwnd, ID_GAMMA ) )
				g_Settings.uGamma = SendMessage ( (HWND) lParam, TBM_GETPOS, 0, 0 );

			else if ( (HWND) lParam == GetDlgItem ( hwnd, ID_BRIGHTNESS ) )
				g_Settings.uBrightness = SendMessage ( (HWND) lParam, TBM_GETPOS, 0, 0 );

			else if ( (HWND) lParam == GetDlgItem ( hwnd, ID_CONTRAST ) )
				g_Settings.uContrast = SendMessage ( (HWND) lParam, TBM_GETPOS, 0, 0 );

			set_gamma_ramp ( ((double)g_Settings.uGamma)/100, g_Settings.uBrightness, g_Settings.uContrast );

		break;

	case WM_COMMAND:

		switch ( LOWORD ( wParam ) )
		{

#if 0
		case ID_TOGGLE:
			g_Settings.bOn = g_Settings.bOn ? false : true;
			if ( g_Settings.bOn )
				set_gamma_ramp ( ((double)g_Settings.uGamma)/100, g_Settings.uBrightness, g_Settings.uContrast );
			else
				set_default_gamma ();
			set_state();
			break;
#endif

		case ID_SHRINK:
			{
				RECT r;
				GetWindowRect ( g_hwnd, &r );
				SetWindowPos ( g_hwndMini, NULL, r.left, r.top, 0, 0, SWP_NOSIZE );
				g_Settings.bExpanded = false;
				set_state();
			}
			break;

		case ID_EXPAND:
			{
				RECT r;
				GetWindowRect ( g_hwndMini, &r );
				SetWindowPos ( g_hwnd, NULL, r.left, r.top, 0, 0, SWP_NOSIZE );
				g_Settings.bExpanded = true;
				set_state();
			}
			break;

		case ID_ON:
			g_Settings.bOn = true;
			set_state ();
			set_gamma_ramp ( ((double)g_Settings.uGamma)/100, g_Settings.uBrightness, g_Settings.uContrast );
			break;

		case ID_OFF:
			g_Settings.bOn = false;
			set_state ();
			set_default_gamma();
			break;

		case IDCANCEL:
			clean_up_for_exit();
			EndDialog(hwnd, LOWORD(wParam));
			exit(0);

		case ID_DEFAULTS:
			{
				cSettings Default;
				Default.init();
				g_Settings.uBrightness = Default.uBrightness;
				g_Settings.uContrast = Default.uContrast;
				g_Settings.uGamma = Default.uGamma;
				SendMessage ( GetDlgItem ( hwnd, ID_BRIGHTNESS ), TBM_SETPOS, TRUE, LPARAM ( g_Settings.uBrightness ) );
				SendMessage ( GetDlgItem ( hwnd, ID_CONTRAST   ), TBM_SETPOS, TRUE, LPARAM ( g_Settings.uContrast) );
				SendMessage ( GetDlgItem ( hwnd, ID_GAMMA      ), TBM_SETPOS, TRUE, LPARAM ( g_Settings.uGamma ) );
				set_gamma_ramp ( ((double)g_Settings.uGamma)/100, g_Settings.uBrightness, g_Settings.uContrast );
			}
			break;
		}
		break;

	case WM_NOTIFY:
		{
			switch( wParam )
			{
			case ID_LINK:

				switch ( ((LPNMHDR)lParam)->code )
				{
					case NM_CLICK:
					case NM_RETURN:
					{
						wchar_t * pURL = PNMLINK(lParam)->item.szUrl;
						ShellExecute ( NULL, L"open", pURL, NULL, NULL, SW_SHOW );
					}
					break;
				}
				break;
			}
        }
		break;
	}

	return (INT_PTR)FALSE;
}

